package com.adopapa.ethexplorer.contoller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.web3j.protocol.core.methods.response.EthBlock.Block;

import com.adopapa.ethexplorer.domain.BlockInfo;
import com.adopapa.ethexplorer.service.BlockInfoService;
import com.adopapa.ethexplorer.service.ChaindataService;
import com.adopapa.ethexplorer.utils.Tools;

import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/api/v1/block")
public class BlockController extends BaseController {

//	@Autowired
//	private Web3j web3j;
	@Autowired
	private ChaindataService chaindataService;
	@Autowired
	private BlockInfoService blockInfoService;

	/**
	 * 分页查询区块
	 */
	@GetMapping(path = "/blocks/{pageNo}", produces = MediaType.APPLICATION_JSON_VALUE)
	public Mono<Map<String, Object>> getBlocks(@PathVariable Integer pageNo,
			@RequestParam(required = false) Integer pageSize) {

		pageSize = Tools.empty(pageSize) ? 10 : pageSize;

//		// query block number
//		BigInteger blockNumber = null;
//		try {
//			EthBlockNumber ehBlockNumber = web3j.ethBlockNumber().send();
//			blockNumber = ehBlockNumber.getBlockNumber();
//		} catch (Exception e) {
//			throw new RuntimeException(e.getMessage());
//		}
//
//		// compute start and end
//		BigInteger start = blockNumber.subtract(BigInteger.valueOf((pageNo - 1) * pageSize));
//		BigInteger end = blockNumber.subtract(BigInteger.valueOf(pageNo * pageSize - 1));
//		if (end.compareTo(BigInteger.ONE) < 0) {
//			end = BigInteger.ONE;
//		}
//
//		DefaultBlockParameter startBlockParameter = DefaultBlockParameter.valueOf(end);
//		DefaultBlockParameter endBlockParameter = DefaultBlockParameter.valueOf(start);
//
//		List<Block> blocks = new LinkedList<Block>();
//		Flowable<EthBlock> flowable = web3j.replayPastBlocksFlowable(startBlockParameter, endBlockParameter, false);
//
//		flowable.blockingForEach(block -> {
//			blocks.add(block.getResult());
//		});
//
//		PageRequest pageRequest = PageRequest.of(pageNo, pageSize);
//		
//		Collections.reverse(blocks);
//
//		Page<EthBlock.Block> page = new PageImpl<EthBlock.Block>(blocks, pageRequest, blockNumber.longValue());
		
		Page<BlockInfo> page = blockInfoService.getBlockInfoPage(pageNo, pageSize, new BlockInfo());

		return Mono.just(ok(page));
	}

	/**
	 * 按区块号查询
	 */
	@GetMapping(path = "/number/{blockNumber}", produces = MediaType.APPLICATION_JSON_VALUE)
	public Mono<Map<String, Object>> getBlockByNumber(@PathVariable Long blockNumber) {

		try {
			Block block = chaindataService.getBlock(blockNumber, true);
			return Mono.just(ok(block));
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}

	}

	
	/**
	 * 按区块hash查询
	 */
	@GetMapping(path = "/hash/{blockHash}", produces = MediaType.APPLICATION_JSON_VALUE)
	public Mono<Map<String, Object>> getBlockByHash(@PathVariable String blockHash) {
		try {
			Block block = chaindataService.getBlock(blockHash, true);
			return Mono.just(ok(block));
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}

}
